package com.teamwork.module01.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.teamwork.module03.service.UserService;
import com.teamwork.common.entity.module01.Class;
import com.teamwork.common.entity.module01.Student;
import com.teamwork.common.constant.RedisConsts;
import com.teamwork.common.result.Result;
import com.teamwork.common.util.RedisUtil;
import com.teamwork.module01.mapper.ClassMapper;
import com.teamwork.module01.mapper.StudentMapper;
import com.teamwork.module01.service.ClassService;
import com.teamwork.module01.service.StudentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

@Service
@Slf4j
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

    @Resource
    private StudentMapper studentMapper;
    @Resource
    private ClassService classService;
    @Resource
    private ClassMapper classMapper;
    @Resource
    private UserService userService;
    @Resource
    private  RedisUtil redisUtil;

    /**
     * 根据姓名查询学生
     * @param name
     * @return
     */
    @Override
    public Result getByName(String name) {

        LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Student::getName,name).or().like(Student::getName,name);

        Student stu = this.getOne(wrapper);
        if(stu==null){
            return Result.failure("该学生不存在");
        }

        return Result.success(stu);
    }

    /**
     * 分页查询
     * @param page
     * @param size
     * @return
     */
    @Override
    public Result getPage(Integer page, Integer size) {
        Page<Student> pageinfo = new Page<>(page,size);

        this.page(pageinfo);

        return Result.success(pageinfo);
    }

    /**
     * 添加或修改学生
     * @param student
     * @return
     */
    @Override
    @Transactional
    public Result InsertOrUpdate(Student student) {
        String key = RedisConsts.MOD01_STU_KEY_PREFIX+student.getStuId();
        //如果id存在，则是修改
        if(student.getId()!=null){
            //先修改redis中数据
            boolean rb = redisUtil.set(key, student);
            //在修改mysql
            boolean mb = this.updateById(student);
            if(rb&&mb){
                log.info("学号为:"+student.getStuId()+"的学生信息被修改...");
                return Result.success("修改成功");
            }else {
                log.error("学号为:"+student.getStuId()+"的学生信息修改失败！！！");
                return Result.failure("修改失败");
            }
        }
        //先判断学号是否重复（学号是学生的唯一标识）
        //先从redis中查询是否存在该学号
        Object o = redisUtil.get(RedisConsts.MOD01_STU_KEY_PREFIX + student.getStuId());
        if(o!=null){
            return Result.failure("该学号已经存在，请重新添加");
        }else {
            //redis中没有，可能是其他原因，这时，再去查询mysql
            LambdaQueryWrapper<Student> wrapper =new LambdaQueryWrapper<>();
            wrapper.eq(Student::getStuId,student.getStuId());
            Student one = this.getOne(wrapper);
            if(one!=null){
                //该学生已经存在，不能添加
                return Result.failure("该学号已经存在，请重新添加");
            }
        }
        //现在，可以保证该学号不存在，可以添加学生了
        //添加学生
        boolean sb = this.save(student);
        //添加到redis
        boolean rb = redisUtil.set(key, student);
        if(sb&&rb) {
            log.info("添加了学号为:"+student.getStuId() +"的一条学生记录...");
            return Result.success("添加成功");
        }
        else if(sb&&!rb){
            //mysql添加成功，redis没有成功
            log.error("添加学号为:"+student.getStuId()+"的学生记录到redis失败！");
            return Result.failure("添加成功!");
        }else if(!sb&&rb){
            //redis添加成功，mysql没成功
            log.error("添加学号为:"+student.getStuId()+"的学生记录到mysql失败！");
            return Result.failure("添加失败！");
        }else {
            //两者都不成功
            log.error("添加学号为:"+student.getStuId()+"的学生记录完全失败！");
            return Result.failure("添加失败");
        }


    }

    /**
     * 单个删除
     * @param id
     * @return
     */
    @Transactional
    @Override
    public Result deleteById(Long id) {
        //先查询出该id的学号
//        Long stuId = studentMapper.selectStuIdById(id);
//        if(stuId==null){
//            return Result.failure("该学生不存在");
//        }
        Student stu = this.getById(id);
        if(stu==null){
            return Result.failure("该学生不存在");
        }

        //删除redis
        boolean srb = redisUtil.del(RedisConsts.MOD01_STU_KEY_PREFIX + stu.getStuId());
        //删除Redis中用户记录
        boolean urb = redisUtil.del(RedisConsts.USER_KEY_PREFIX + stu.getUserId());

        //先把用户表中的记录删除
        boolean ub = userService.removeById(stu.getUserId());
        //删除学生表中的记录
        boolean mb = this.removeById(id);
        //先查询出该学生所在班级人数
       //Integer number = classService.getById(stu.getClassId()).getNumber();
        Integer number = classMapper.getNumberById(stu.getClassId());

        //将该学生所在班级人数减一
        UpdateWrapper<Class> updateWrapper =new UpdateWrapper<>();
        updateWrapper.eq("id",stu.getClassId()).set("number",number-1);
        classService.update(null,updateWrapper);
        //



        if(ub&&mb&&srb&&urb){
            log.info("删除了一条学号为:"+stu.getStuId()+"的学生记录，同时删除了用户id为:"+stu.getUserId()+"的用户记录..." +
                    "班级id为:"+stu.getClassId()+"的班级人数减一");
            return Result.success("删除成功");
        }else if(ub&&mb && (!srb||!urb)){
            log.error("删除了学号为:"+stu.getStuId()+"的学生记录，同时删除用户id为:"+stu.getUserId()+"的用户记录" +
                    " mysql删除成功，redis删除失败!!!");
            return Result.failure("mysql删除成功，redis删除失败");
        }else if(srb&&urb && (!ub||!mb)){
            log.error("删除了学号为:"+stu.getStuId()+"的学生记录，同时删除用户id为:"+stu.getUserId()+"的用户记录" +
                    " redis删除成功，mysql删除失败!!!");
            return Result.failure("redis删除成功，mysql删除失败");
        }

        return Result.failure("删除失败");
    }

    /**
     * 批量删除
     * @param ids
     * @return
     */
    @Override
    public Result batchDelete(List<Long> ids) {

        for (Long id : ids) {
            Long stuId = studentMapper.selectStuIdById(id);
            String key = RedisConsts.MOD01_STU_KEY_PREFIX + stuId;
            //redis删除是否成功的标志
            boolean rb=false;
            if (redisUtil.hasKey(key)){
                //redis中存在，删除
              rb = redisUtil.del(key);
            }

            boolean b = this.removeById(id);


        }
        //转换为字符数组
       // String[] keys = stuids.toArray(new String[0]);



        return Result.success("删除成功");
    }

    /**
     * 根据学号查询学生
     * @param stuid
     * @return
     */
    @Override
    public Result getByStuId(Long stuid) {
        //先查询redis
        String key = RedisConsts.MOD01_STU_KEY_PREFIX+stuid;

        Object o = redisUtil.get(key);

        if(o!=null){
            return Result.success(o);
        }
        //redis中不存在，
        //查询mysql
        LambdaQueryWrapper<Student> wrapper =new LambdaQueryWrapper<>();
        wrapper.eq(Student::getStuId,stuid);
        Student stu = this.getOne(wrapper);
        if(stu==null) return Result.failure("该学生不存在");

        //查询到，先写入redis中去，
        redisUtil.set(key,stu);


        return Result.success(stu);
    }
}
